use actix_web::{web, App, HttpServer, middleware::Logger};
use tracing_actix_web::TracingLogger;

mod config;
mod database;
mod handlers;
mod middleware;
mod models;
mod services;
mod utils;
mod error;

use config::AppConfig;
use database::Database;
use error::AppResult;

#[actix_web::main]
async fn main() -> AppResult<()> {
    // Initialize tracing
    tracing_subscriber::fmt()
        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
        .init();

    // Load configuration
    let config = AppConfig::load()?;
    
    // Initialize database
    let db = Database::new(&config.database_url).await?;
    
    tracing::info!("Starting server at {}:{}", config.host, config.port);
    
    // Capture bind parameters before moving config into the closure
    let host = config.host.clone();
    let port = config.port;

    // Start HTTP server
    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(db.clone()))
            .app_data(web::Data::new(config.clone()))
            .wrap(TracingLogger::default())
            .wrap(Logger::default())
            .wrap(middleware::cors::cors())
            .wrap(middleware::auth::AuthMiddleware)
            .configure(handlers::configure_routes)
    })
    .bind((host, port))?
    .run()
    .await
    .map_err(Into::into)
}